{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "from time import time\n",
    "import numpy as np\n",
    "import keras.backend as K\n",
    "from keras.engine.topology import Layer, InputSpec\n",
    "from keras.layers import Dense, Input\n",
    "from keras.models import Model\n",
    "from keras.optimizers import SGD\n",
    "from keras import callbacks\n",
    "from keras.initializers import VarianceScaling\n",
    "from sklearn.cluster import KMeans\n",
    "import metrics\n",
    "from keras.datasets import mnist\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "from numpy import float32\n",
    "np.random.seed(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "train = pd.read_csv('C:/Users/admin-karim/Downloads/TCGA_train.csv', dtype=float32, delimiter=',')\n",
    "test = pd.read_csv('C:/Users/admin-karim/Downloads/TCGA_test.csv', dtype=float32, delimiter=',')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(599, 20532)"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "X1 = train.iloc[0:20531]\n",
    "y1 = train.iloc[:,-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "X2 = test.iloc[0:20531]\n",
    "y2 = test.iloc[:,-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = np.concatenate((X1,X2)) \n",
    "y = np.concatenate((y1,y2)) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "(799, 20532)"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "n_clusters = len(np.unique(y))\n",
    "print(n_clusters)\n",
    "x.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Base line K-Means clustering accuracy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "kmeans = KMeans(n_clusters=n_clusters, n_init=20, n_jobs=4)\n",
    "y_pred_kmeans = kmeans.fit_predict(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "c:\\users\\admin-karim\\appdata\\local\\programs\\python\\python35\\lib\\site-packages\\sklearn\\utils\\linear_assignment_.py:21: DeprecationWarning: The linear_assignment_ module is deprecated in 0.21 and will be removed from 0.23. Use scipy.optimize.linear_sum_assignment instead.\n",
      "  DeprecationWarning)\n",
      "c:\\users\\admin-karim\\appdata\\local\\programs\\python\\python35\\lib\\site-packages\\sklearn\\utils\\linear_assignment_.py:127: DeprecationWarning: The linear_assignment function is deprecated in 0.21 and will be removed from 0.23. Use scipy.optimize.linear_sum_assignment instead.\n",
      "  DeprecationWarning)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "0.9924906132665833"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "metrics.acc(y, y_pred_kmeans)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [],
   "source": [
    "def autoencoder(dims, act='relu', init='glorot_uniform'):\n",
    "    \"\"\"\n",
    "    Fully connected auto-encoder model, symmetric.\n",
    "    Arguments:\n",
    "        dims: list of number of units in each layer of encoder. dims[0] is input dim, dims[-1] is units in hidden layer.\n",
    "            The decoder is symmetric with encoder. So number of layers of the auto-encoder is 2*len(dims)-1\n",
    "        act: activation, not applied to Input, Hidden and Output layers\n",
    "    return:\n",
    "        (ae_model, encoder_model), Model of autoencoder and model of encoder\n",
    "    \"\"\"\n",
    "    n_stacks = len(dims) - 1\n",
    "    # input\n",
    "    input_img = Input(shape=(dims[0],), name='input')\n",
    "    x = input_img\n",
    "    # internal layers in encoder\n",
    "    for i in range(n_stacks-1):\n",
    "        x = Dense(dims[i + 1], activation=act, kernel_initializer=init, name='encoder_%d' % i)(x)\n",
    "\n",
    "    # hidden layer\n",
    "    encoded = Dense(dims[-1], kernel_initializer=init, name='encoder_%d' % (n_stacks - 1))(x)  # hidden layer, features are extracted from here\n",
    "\n",
    "    x = encoded\n",
    "    # internal layers in decoder\n",
    "    for i in range(n_stacks-1, 0, -1):\n",
    "        x = Dense(dims[i], activation=act, kernel_initializer=init, name='decoder_%d' % i)(x)\n",
    "\n",
    "    # output\n",
    "    x = Dense(dims[0], kernel_initializer=init, name='decoder_0')(x)\n",
    "    decoded = x\n",
    "    return Model(inputs=input_img, outputs=decoded, name='AE'), Model(inputs=input_img, outputs=encoded, name='encoder')\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Defining hyperparameters"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [],
   "source": [
    "dims = [20532, 64, 128, 256, 5]\n",
    "init = VarianceScaling(scale=1. / 3., mode='fan_in', distribution='uniform')\n",
    "pretrain_optimizer = SGD(lr=0.01, momentum=0.9)\n",
    "pretrain_epochs = 100\n",
    "batch_size = 256\n",
    "save_dir = 'results/'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [],
   "source": [
    "autoencoder, encoder = autoencoder(dims, init=init)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Pretrain auto-encoder"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/100\n",
      "799/799 [==============================] - 1s 1ms/step - loss: 57.8638\n",
      "Epoch 2/100\n",
      "799/799 [==============================] - 1s 972us/step - loss: 57.8393\n",
      "Epoch 3/100\n",
      "799/799 [==============================] - 1s 969us/step - loss: 57.7859\n",
      "Epoch 4/100\n",
      "799/799 [==============================] - 1s 942us/step - loss: 57.6916\n",
      "Epoch 5/100\n",
      "799/799 [==============================] - 1s 935us/step - loss: 57.5317\n",
      "Epoch 6/100\n",
      "799/799 [==============================] - 1s 932us/step - loss: 57.2653\n",
      "Epoch 7/100\n",
      "799/799 [==============================] - 1s 935us/step - loss: 56.8257\n",
      "Epoch 8/100\n",
      "799/799 [==============================] - 1s 932us/step - loss: 56.1047\n",
      "Epoch 9/100\n",
      "799/799 [==============================] - 1s 966us/step - loss: 54.9359\n",
      "Epoch 10/100\n",
      "799/799 [==============================] - 1s 934us/step - loss: 53.0804\n",
      "Epoch 11/100\n",
      "799/799 [==============================] - 1s 946us/step - loss: 51.1417\n",
      "Epoch 12/100\n",
      "799/799 [==============================] - 1s 955us/step - loss: 57.6560\n",
      "Epoch 13/100\n",
      "799/799 [==============================] - 1s 995us/step - loss: 57.2162\n",
      "Epoch 14/100\n",
      "799/799 [==============================] - 1s 947us/step - loss: 81.2474\n",
      "Epoch 15/100\n",
      "799/799 [==============================] - 1s 1ms/step - loss: 57.7474\n",
      "Epoch 16/100\n",
      "799/799 [==============================] - 1s 1ms/step - loss: 57.6188\n",
      "Epoch 17/100\n",
      "799/799 [==============================] - 1s 947us/step - loss: 57.4407\n",
      "Epoch 18/100\n",
      "799/799 [==============================] - 1s 927us/step - loss: 57.2399\n",
      "Epoch 19/100\n",
      "799/799 [==============================] - 1s 935us/step - loss: 57.0298\n",
      "Epoch 20/100\n",
      "799/799 [==============================] - 1s 932us/step - loss: 56.8001\n",
      "Epoch 21/100\n",
      "799/799 [==============================] - 1s 932us/step - loss: 56.5496\n",
      "Epoch 22/100\n",
      "799/799 [==============================] - 1s 940us/step - loss: 56.2792\n",
      "Epoch 23/100\n",
      "799/799 [==============================] - 1s 934us/step - loss: 55.9732\n",
      "Epoch 24/100\n",
      "799/799 [==============================] - 1s 944us/step - loss: 55.6178\n",
      "Epoch 25/100\n",
      "799/799 [==============================] - 1s 929us/step - loss: 55.1686\n",
      "Epoch 26/100\n",
      "799/799 [==============================] - 1s 939us/step - loss: 54.5065\n",
      "Epoch 27/100\n",
      "799/799 [==============================] - 1s 939us/step - loss: 53.2439\n",
      "Epoch 28/100\n",
      "799/799 [==============================] - 1s 1ms/step - loss: 49.5881\n",
      "Epoch 29/100\n",
      "799/799 [==============================] - 1s 935us/step - loss: 35.0149\n",
      "Epoch 30/100\n",
      "799/799 [==============================] - 1s 934us/step - loss: 28.8801\n",
      "Epoch 31/100\n",
      "799/799 [==============================] - 1s 945us/step - loss: 21.3339\n",
      "Epoch 32/100\n",
      "799/799 [==============================] - 1s 934us/step - loss: 13.2882\n",
      "Epoch 33/100\n",
      "799/799 [==============================] - 1s 927us/step - loss: 8.0567\n",
      "Epoch 34/100\n",
      "799/799 [==============================] - 1s 935us/step - loss: 5.0008\n",
      "Epoch 35/100\n",
      "799/799 [==============================] - 1s 927us/step - loss: 3.3226\n",
      "Epoch 36/100\n",
      "799/799 [==============================] - 1s 929us/step - loss: 2.3199\n",
      "Epoch 37/100\n",
      "799/799 [==============================] - 1s 939us/step - loss: 1.9940\n",
      "Epoch 38/100\n",
      "799/799 [==============================] - 1s 936us/step - loss: 1.9412\n",
      "Epoch 39/100\n",
      "799/799 [==============================] - 1s 940us/step - loss: 1.9222\n",
      "Epoch 40/100\n",
      "799/799 [==============================] - 1s 944us/step - loss: 1.9418\n",
      "Epoch 41/100\n",
      "799/799 [==============================] - 1s 927us/step - loss: 1.9536\n",
      "Epoch 42/100\n",
      "799/799 [==============================] - 1s 935us/step - loss: 1.9185\n",
      "Epoch 43/100\n",
      "799/799 [==============================] - 1s 939us/step - loss: 1.8694\n",
      "Epoch 44/100\n",
      "799/799 [==============================] - 1s 932us/step - loss: 1.8291\n",
      "Epoch 45/100\n",
      "799/799 [==============================] - 1s 934us/step - loss: 1.7977\n",
      "Epoch 46/100\n",
      "799/799 [==============================] - 1s 947us/step - loss: 1.7763\n",
      "Epoch 47/100\n",
      "799/799 [==============================] - 1s 936us/step - loss: 1.7681\n",
      "Epoch 48/100\n",
      "799/799 [==============================] - 1s 944us/step - loss: 1.7645\n",
      "Epoch 49/100\n",
      "799/799 [==============================] - 1s 939us/step - loss: 1.7624\n",
      "Epoch 50/100\n",
      "799/799 [==============================] - 1s 929us/step - loss: 1.7624\n",
      "Epoch 51/100\n",
      "799/799 [==============================] - 1s 930us/step - loss: 1.7630\n",
      "Epoch 52/100\n",
      "799/799 [==============================] - 1s 945us/step - loss: 1.7628\n",
      "Epoch 53/100\n",
      "799/799 [==============================] - 1s 936us/step - loss: 1.7631\n",
      "Epoch 54/100\n",
      "799/799 [==============================] - 1s 940us/step - loss: 1.7627\n",
      "Epoch 55/100\n",
      "799/799 [==============================] - 1s 925us/step - loss: 1.7622\n",
      "Epoch 56/100\n",
      "799/799 [==============================] - 1s 937us/step - loss: 1.7624\n",
      "Epoch 57/100\n",
      "799/799 [==============================] - 1s 935us/step - loss: 1.7619\n",
      "Epoch 58/100\n",
      "799/799 [==============================] - 1s 941us/step - loss: 1.7617\n",
      "Epoch 59/100\n",
      "799/799 [==============================] - 1s 934us/step - loss: 1.7618\n",
      "Epoch 60/100\n",
      "799/799 [==============================] - 1s 950us/step - loss: 1.7617\n",
      "Epoch 61/100\n",
      "799/799 [==============================] - 1s 945us/step - loss: 1.7616\n",
      "Epoch 62/100\n",
      "799/799 [==============================] - 1s 1ms/step - loss: 1.7618\n",
      "Epoch 63/100\n",
      "799/799 [==============================] - 1s 1ms/step - loss: 1.7620\n",
      "Epoch 64/100\n",
      "799/799 [==============================] - 1s 940us/step - loss: 1.7617\n",
      "Epoch 65/100\n",
      "799/799 [==============================] - 1s 930us/step - loss: 1.7617\n",
      "Epoch 66/100\n",
      "799/799 [==============================] - 1s 1ms/step - loss: 1.7617\n",
      "Epoch 67/100\n",
      "799/799 [==============================] - 1s 989us/step - loss: 1.7618\n",
      "Epoch 68/100\n",
      "799/799 [==============================] - 1s 925us/step - loss: 1.7616\n",
      "Epoch 69/100\n",
      "799/799 [==============================] - 1s 940us/step - loss: 1.7621\n",
      "Epoch 70/100\n",
      "799/799 [==============================] - 1s 929us/step - loss: 1.7619\n",
      "Epoch 71/100\n",
      "799/799 [==============================] - 1s 946us/step - loss: 1.7620\n",
      "Epoch 72/100\n",
      "799/799 [==============================] - 1s 936us/step - loss: 1.7618\n",
      "Epoch 73/100\n",
      "799/799 [==============================] - 1s 939us/step - loss: 1.7616\n",
      "Epoch 74/100\n",
      "799/799 [==============================] - 1s 946us/step - loss: 1.7616\n",
      "Epoch 75/100\n",
      "799/799 [==============================] - 1s 989us/step - loss: 1.7618\n",
      "Epoch 76/100\n",
      "799/799 [==============================] - 1s 935us/step - loss: 1.7616\n",
      "Epoch 77/100\n",
      "799/799 [==============================] - 1s 941us/step - loss: 1.7617\n",
      "Epoch 78/100\n",
      "799/799 [==============================] - 1s 964us/step - loss: 1.7617\n",
      "Epoch 79/100\n",
      "799/799 [==============================] - 1s 936us/step - loss: 1.7628\n",
      "Epoch 80/100\n",
      "799/799 [==============================] - 1s 950us/step - loss: 1.7622\n",
      "Epoch 81/100\n",
      "799/799 [==============================] - 1s 931us/step - loss: 1.7618\n",
      "Epoch 82/100\n",
      "799/799 [==============================] - 1s 939us/step - loss: 1.7618\n",
      "Epoch 83/100\n",
      "799/799 [==============================] - 1s 942us/step - loss: 1.7616\n",
      "Epoch 84/100\n",
      "799/799 [==============================] - 1s 947us/step - loss: 1.7617\n",
      "Epoch 85/100\n",
      "799/799 [==============================] - 1s 931us/step - loss: 1.7621\n",
      "Epoch 86/100\n",
      "799/799 [==============================] - 1s 941us/step - loss: 1.7621\n",
      "Epoch 87/100\n",
      "799/799 [==============================] - 1s 939us/step - loss: 1.7622\n",
      "Epoch 88/100\n",
      "799/799 [==============================] - 1s 926us/step - loss: 1.7617\n",
      "Epoch 89/100\n",
      "799/799 [==============================] - 1s 939us/step - loss: 1.7616\n",
      "Epoch 90/100\n",
      "799/799 [==============================] - 1s 931us/step - loss: 1.7617\n",
      "Epoch 91/100\n",
      "799/799 [==============================] - 1s 970us/step - loss: 1.7618\n",
      "Epoch 92/100\n",
      "799/799 [==============================] - 1s 969us/step - loss: 1.7618\n",
      "Epoch 93/100\n",
      "799/799 [==============================] - 1s 940us/step - loss: 1.7619\n",
      "Epoch 94/100\n",
      "799/799 [==============================] - 1s 931us/step - loss: 1.7620\n",
      "Epoch 95/100\n",
      "799/799 [==============================] - 1s 934us/step - loss: 1.7620\n",
      "Epoch 96/100\n",
      "799/799 [==============================] - 1s 939us/step - loss: 1.7622\n",
      "Epoch 97/100\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "799/799 [==============================] - 1s 942us/step - loss: 1.7618\n",
      "Epoch 98/100\n",
      "799/799 [==============================] - 1s 927us/step - loss: 1.7620\n",
      "Epoch 99/100\n",
      "799/799 [==============================] - 1s 929us/step - loss: 1.7618\n",
      "Epoch 100/100\n",
      "799/799 [==============================] - 1s 946us/step - loss: 1.7618\n"
     ]
    }
   ],
   "source": [
    "autoencoder.compile(optimizer=pretrain_optimizer, loss='mse')\n",
    "autoencoder.fit(x, x, batch_size=batch_size, epochs=pretrain_epochs) #, callbacks=cb)\n",
    "autoencoder.save_weights(save_dir + '/ae_weights.h5')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [],
   "source": [
    "autoencoder.save_weights(save_dir + '/ae_weights.h5')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Load the pre-trained auto encoder weights"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [],
   "source": [
    "autoencoder.load_weights(save_dir + '/ae_weights.h5')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Build clustering model"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### ClusteringLayer"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [],
   "source": [
    "class ClusteringLayer(Layer):\n",
    "    \"\"\"\n",
    "    Clustering layer converts input sample (feature) to soft label, i.e. a vector that represents the probability of the\n",
    "    sample belonging to each cluster. The probability is calculated with student's t-distribution.\n",
    "\n",
    "    # Example\n",
    "    ```\n",
    "        model.add(ClusteringLayer(n_clusters=10))\n",
    "    ```\n",
    "    # Arguments\n",
    "        n_clusters: number of clusters.\n",
    "        weights: list of Numpy array with shape `(n_clusters, n_features)` witch represents the initial cluster centers.\n",
    "        alpha: degrees of freedom parameter in Student's t-distribution. Default to 1.0.\n",
    "    # Input shape\n",
    "        2D tensor with shape: `(n_samples, n_features)`.\n",
    "    # Output shape\n",
    "        2D tensor with shape: `(n_samples, n_clusters)`.\n",
    "    \"\"\"\n",
    "\n",
    "    def __init__(self, n_clusters, weights=None, alpha=1.0, **kwargs):\n",
    "        if 'input_shape' not in kwargs and 'input_dim' in kwargs:\n",
    "            kwargs['input_shape'] = (kwargs.pop('input_dim'),)\n",
    "        super(ClusteringLayer, self).__init__(**kwargs)\n",
    "        self.n_clusters = n_clusters\n",
    "        self.alpha = alpha\n",
    "        self.initial_weights = weights\n",
    "        self.input_spec = InputSpec(ndim=2)\n",
    "\n",
    "    def build(self, input_shape):\n",
    "        assert len(input_shape) == 2\n",
    "        input_dim = input_shape[1]\n",
    "        self.input_spec = InputSpec(dtype=K.floatx(), shape=(None, input_dim))\n",
    "        self.clusters = self.add_weight((self.n_clusters, input_dim), initializer='glorot_uniform', name='clusters')\n",
    "        if self.initial_weights is not None:\n",
    "            self.set_weights(self.initial_weights)\n",
    "            del self.initial_weights\n",
    "        self.built = True\n",
    "\n",
    "    def call(self, inputs, **kwargs):\n",
    "        \"\"\" student t-distribution, as same as used in t-SNE algorithm.\n",
    "         Measure the similarity between embedded point z_i and centroid µ_j.\n",
    "                 q_ij = 1/(1+dist(x_i, µ_j)^2), then normalize it.\n",
    "                 q_ij can be interpreted as the probability of assigning sample i to cluster j.\n",
    "                 (i.e., a soft assignment)\n",
    "        Arguments:\n",
    "            inputs: the variable containing data, shape=(n_samples, n_features)\n",
    "        Return:\n",
    "            q: student's t-distribution, or soft labels for each sample. shape=(n_samples, n_clusters)\n",
    "        \"\"\"\n",
    "        q = 1.0 / (1.0 + (K.sum(K.square(K.expand_dims(inputs, axis=1) - self.clusters), axis=2) / self.alpha))\n",
    "        q **= (self.alpha + 1.0) / 2.0\n",
    "        q = K.transpose(K.transpose(q) / K.sum(q, axis=1)) # Make sure each sample's 10 values add up to 1.\n",
    "        return q\n",
    "\n",
    "    def compute_output_shape(self, input_shape):\n",
    "        assert input_shape and len(input_shape) == 2\n",
    "        return input_shape[0], self.n_clusters\n",
    "\n",
    "    def get_config(self):\n",
    "        config = {'n_clusters': self.n_clusters}\n",
    "        base_config = super(ClusteringLayer, self).get_config()\n",
    "        return dict(list(base_config.items()) + list(config.items()))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [],
   "source": [
    "clustering_layer = ClusteringLayer(n_clusters, name='clustering')(encoder.output)\n",
    "model = Model(inputs=encoder.input, outputs=clustering_layer)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZcAAAJzCAYAAADDW14EAAAABmJLR0QA/wD/AP+gvaeTAAAgAElEQVR4nOzdf2gbZ54/8Leapr2l7MnkDjlp7tzbpZtS6K426ZG6ey0hbriQ7I7Sg9q17HWzC0oYs23JErHs+mRCsNftgsSW9o8Y2SzfIByJun90Ja75JzY4LLFTbosEV0rN0q3MXlmJXdBs4aDNdp/vH+4zmRmNpJE81kj2+wUi0cyjmWcejeejeeb54RNCCBAREbnnxXu8zgEREe08DC5EROQ6BhciInIdgwsREbnuXq8zYJTL5ZBKpbzOBhFRV9mzZw9++ctfYv/+/V5nRddRdy6ZTAaLi4teZ4N2kI2NDZ5TDt2+fRu3b9/2OhvUgkwmg+XlZa+zYdJRdy4AMDIygoWFBa+zQTvEtWvXMDo6ijfffNPrrHS80dFRAODfXxfy+XxeZ6FKR925EBHRzsDgQkRErmNwISIi1zG4EBGR6xhciIjIdQwuRA5NTk5icnLS62x0rHK5jEQi4XU2ulIikYCmaV5nw1UMLkRdQtO0jmxyCmwGlkuXLuHw4cPw+Xzw+Xw1A7Fcb3x1Ilnedq9MJmNKm8vlEAqF4PP5EAqFqtZbzc3NmY77xIkTGBsbQ7lc3pZj8ULH9XMh6lRTU1Oe7v/mzZue7r8WTdMQiUQwMTGB/v5+VCoVXL9+HeFwGEB1uQkhUC6X0dvbi1KphEAg4EW2G/rggw9qrhsYGND/n0gkEI1Gkc/nkc1mUSgU8O1vfxv/+7//i4sXL1Z9tlAo4Pz586ZlwWAQExMTiEQiSKVS8Pv97h2IR3jnQtQFNE3D3Nyc19mwNT8/j2AwiP7+fgCA3+/H8PAwAGB6etr2V7wMKJ0aWADg448/RrFYhBBCf5VKJcRiMVO+o9EogM0AYfx3ZWWlapuapuGtt96y3V9/fz8OHjyI+fl5tw/FEwwuRA6Uy2VkMhmEQiHb97lcTq8S2djY0NPI6hLgblXI+Pg41tfX9W3bVQ9Zl8XjceRyOdM6wPvnQOVyGdFoFMePH7ddH4/HEQ6HG1YTSZqmIZPJ6Mc4NzdnqipyUu7GtIlEQl/f7PAoAwMD6OvrMy1bXl7Gc889V3WMALC2tgYAej7s7nTn5+fx0ksv1dzn4OAgotHozqgeEx1kZGREjIyMeJ0N2kEWFhaEG6e5oigCgL4t4/vV1VUhhBDFYlEAEKqqCiGEvt6YplKpCFVVBQDx4YcfCiGEKJVKpm0bt2VcZn0vhBCxWEzEYrEtH58Qrf39ZbNZAUAUi8WqdTKvsVhMABD5fN52vZGiKCKZTAohNstFURShKIqoVCr6+kblbvxsOp0WQgixtLRkm4dmGfdhJI9xdXVVpNNpUSqVqtIsLS3pebb7Lo3Hks1mm8oXALGwsNDUZ7bZjxhcaEdzK7gIUX1BsLtAOEmTz+cFABGPx7e8LTe18vcnL6p25PJKpaIHBRlQjeslGQCMF+bV1VUBQA8S8nONyiqdTtum2UogzufzpnxYyR8NsVhMD4ZSqVTSg2atYxBis6ys54YTnRhcWC1G1GayTl7W1Xez6enphmn8fr/+HKFelY8cvdr4POPRRx8FsDkAaTNkemv1opP81vLWW2+ZHuQbJRIJHDt2DJVKBQAwNjZmalr861//GufOnWu4D/kgfyecGwwuRLTtAoEA8vk8crkcIpGIbZ+O2dnZqmXyYiufNzkl0wvDw3j5aoUMiHYNEDKZDKLRKE6dOgW/34+xsTHkcjl9JO5cLoeTJ0+2tN9uxuBC5BFVVb3OQlsFg0Fks1nkcjn9IbiRoigAYHtn02pZGRtObIXdg3xJNrmWgbC3txcA9ObGoVAIDz30UM2GGzsVgwtRm8kL3unTpz3OydbJIOG0d7miKEin07bVUyMjIwCAjz76SF8mtzs4ONhUvpLJJAAglUrp29jKCAIrKyt6daaVDIqSDDJyeb27p1p3UrFYrKV8dhIGFyIHrM1hje/lxct4gbX++pZNcTVNQyqVgqIopouS/GUuA49s1goA4+PjAMy/7OVF0uumyIcOHQJQHVzk8dvdhQwPD9tePE+dOgVFUTAzM6N/7vr161BVVX/W4bTcz5w5A2DzGUtPTw98Ph96e3v1ICWbKBcKhYbHWCgUcOzYsZrrL1y4AODudyy/O7m8GbIZ89GjR5v+bKdhcCFyQFZ1yP8b3/f09Jj+taYHNh9Mh0Ih9PT0oK+vD6lUyrT+Zz/7GRRFwSOPPIJcLof+/n79V/7ly5cB3O038cYbb2BsbMzdA2zRE088AQD45JNP9GXyQg5sloNd1c/U1JTtL/75+XkoimL63KuvvqqncVrugUAAxWJRD2KqqqJYLOr9ViqVClRVdRSY6z3IBzb7wywtLWFlZQU+nw9Xr17F0tJS3c/UIstRlms384lWn3BtA06zSm6T0xx7dZrLC2QH/ZnV1Orfn7yLshvqpB5N0zwf5iQUCiGbzXqaB6PJyUn09PQ0XZY+nw8LCwt61WIHeJF3LkS0JZFIBCsrK6aqPCe8Dixra2uYmJjwNA9GhUIBhUIBkUjE66y4gsGFaJtYn9PsVLI6a2ZmxtEzjE6wvLyMffv26eOheW19fR2zs7OYn5/3POi6peuDi9cPNIlqsT6n2ckCgQBSqRRu3LjhdVYcGRgY0BsjdIJcLofLly939ECezeKQ+1ukaRp6enqaqlOv1bbdi3p5a/47KW/dbreVmd/vb/pZAW3aieXW9cGlG+fYEELoF3Vgs+WKV7fC1vwLw1wbgLd5I6Lu1fXVYl7ayhwbxgu2VxfvWvk33pozsBBRK7o6uOy0OTY6Jf/NkAHKOLWtcR4N+TL2jDauMx6X3dwbxuPVNA3j4+N8xkbUDdo5BnMjzQ753e1zbFg/2yn5r7fcSu63VCpV5VUOl243B4aiKPrQ6vXm3rCWST6frzmnhh03h9zf6TjlRfdCBw6531F/da2c3E4ulk7SeDHHhpPte5V/p8cVi8VMF3vr5+LxuADMk0lZ58VoNPeG3KZ1jgwnGFycY3DpXgwuDXgZXNzeVit576T8N3tcxWJRDyTGz8mgZ5woKR6Pm4KN8e7E+molL0YyuPDF105/dVpw6frWYuS9ubk5fRh16yRHwWAQqqri/PnzGBoaAgD87ne/M81Nbpx7Y7vIuTWottdffx0A8PLLL3ucE2qW/NvqJAwuFt0+x0a78j8+Po4rV64gk8ng/PnzpkEB7fI0OzuL69ev44EHHsDZs2dt062vr29bx7Zmh2zfjd5++20ALCtyR1e3FnNTt8+x0c78r62t6UOQy4mSagUW4O7dSzgcxtzcXNWQG27PvUFE3uvq4NLNc2wY82W8oHZC/uuNg7W2toYnn3xSn9tcfn5jY8PUFNq6DXm3Yh1mHag/98ZOHpOLaEfz+qmPUbMP9NHgAZddGuMyY1PXZDJZ1RqpWCzq67PZrBBC6E1mZTNa+cA6Fovpyxo1RW6Uby/z7zRvcl/Wz8vWY8YH9pKiKHpTaatisShisZgAYPq8cZ+KotQs01rYWsw5thbrXujAB/q7cj6Xbppjw0435l/TNPz0pz/FlStX2rpfr+dz6SacT6l7cT4X2rXefPNNPigm2kV2XXDp9jk2uin/k5OTpmFeWpn2lboHG2G0LpFImJ6v7gS7Lrh0+xwb3ZR/2YIsmUx6Pnq1VzRNa2nMtk7ZvlPlchmXLl3C4cOHTePM2TGOOdfqmHbtIMvW7iUb00hy/Ds5Np51vZUcj086ceIExsbGOv4HYzN2XXARQphe3aab8n/u3DkIIXDu3Dmvs+KZVqZk6KTtO6FpGiKRCM6ePYuBgQFUKhWk02lMT0/bBhghBEqlEgCgVCp17Hn8wQcf1FxnvAtPJBIIhUKYmpqCEAJTU1MIh8M17+IKhQLOnz9vWhYMBjExMYFIJLJj7mB2XXAhapetTMnQCdt3an5+HsFgUO+/5Pf7MTw8DGCzebndr3g5rUMnz7z48ccfo1gsmn7MlUolxGIxU77lqBTBYND078rKStU2NU3DW2+9Zbu//v5+HDx4EPPz824fiicYXIhsaJqGTCajV4PMzc2ZqixandKgk6d8aEW5XEY0GsXx48dt18fjcYTD4YbVRFKjcncyLYUxrd00Dk4NDAxUdQ5eXl7Gc889V3WMwN1+ZDIfdlXB8/PzeOmll2ruc3BwENFodEdUjzG4ENkYGxvDp59+qv9azeVypioLWa1jVCwWTe+NFxf5y7e3txehUAi5XA5ra2s4d+4cKpUKAOCRRx7RA0yr22+327dvAwAefvhh2/UXL15ELBZDOBxGoVBouL1G5R6JRBAOh/XyUxQFxWIRuVwOr7zyir6dcrmMSCSCgwcPQgiBCxcu4JlnnnGUB8nurmplZUW/M7Ee45NPPom1tTXcunULpVKpKt3y8jL+7d/+re7dmixHWa5drU0dahxhJy5yWyudKOV8MrKjqRB356YxThUAQ8fWWsucpBHCmykfrFr5+5MdX+3I5ZVKRe/Ma+xEa/2cm+XeaBqHVlinirCScxvFYrGqDs2lUsk0Mnit761SqVSdB06gAztR8s6FyGJxcRGA+ZerHO7m2rVr27JP+SvXOqp0p5uenm6Yxu/3688R6lX5uFnuMr21KtFJfmt56623ajanTyQSOHbsmH4XOjY2Znow/+tf/9pRwxY5rXi3nQd2GFyILGZnZ6uWyT96+YyDmhMIBJDP56uquYzcLHfjNA7WVytkQLSr0spkMohGozh16hT8fj/GxsaQy+X0aR5yuRxOnjzZ0n67GYMLkYVxME+r7Z7SoNunfKgnGAwim83qc/9YbUe5GxtJbIXdg3xJjgwuA6HsfyabG4dCITz00EM1G2nsVAwuRBZyfKaPPvpIXyZ/aW/XEDbdOuWDDBJO+2YoiqL3gbFys9zdnsbB7kG+ZB3pWwYZubze3VOtO6lYLNZSPjsJgwuRxalTp6AoCmZmZvRf0devX4eqqqY691anNJC8nPLBLXJyN2twkeVmdxcyPDxse/F0Uu5Op6WoN40DAL2JspPWY4VCQZ+/yM6FCxcA3P0+5fcklzdDNmM+evRo05/tOB61JLDF1mLktlaH3Jete/Blq550Ou3alAxym15N+VBLK39/cpqG1dVVfZk8PuPLjt0UCo3K3W67tfZVaxoHIYQ+NYSTaRyMZVvL0tKS3lpMVVWxtLRUN32tcpGt4xrtz257ndZabFcOuU+7RycOud+pUya0+vcn75guXrzY1Oc0TdOrkLwSCoWQzWY9zYPR5OQkenp6mi5LDrlPRDtOJBLBysqKqdrOCa8Dy9raGiYmJjzNg1GhUEChUEAkEvE6K65gcCFqo26aMsEp2Y9lZmamqR7wXlpeXsa+ffv08dC8tr6+jtnZWczPz3sedN3C4ELURt00ZUIzAoEAUqkUbty44XVWHBkYGNAbI3SCXC6Hy5cvd/RAns261+sMEO0mnfacxU1+v7/pZwW0aSeWG+9ciIjIdQwuRETkOgYXIiJyHYMLERG5ruMe6C8uLuLZZ5/1Ohu0Q8hJl+Rw7lSbHHqEZUVu6Kjg8rWvfQ137tzB0NCQ11mhHYbnlHO/+c1vvM4CtaDWbKBe6ajhX4g6VScOI0PUwTj8CxERuY/BhYiIXMfgQkRErmNwISIi1zG4EBGR6xhciIjIdQwuRETkOgYXIiJyHYMLERG5jsGFiIhcx+BCRESuY3AhIiLXMbgQEZHrGFyIiMh1DC5EROQ6BhciInIdgwsREbmOwYWIiFzH4EJERK5jcCEiItcxuBARkesYXIiIyHUMLkRE5DoGFyIich2DCxERuY7BhYiIXMfgQkRErmNwISIi1zG4EBGR6xhciIjIdQwuRETkOgYXIiJyHYMLERG57l6vM0DUid588038/ve/19/n83kAwC9+8QtTuu9+97t47LHH2po3om7gE0IIrzNB1Gl8Ph8A4P7776+Z5rPPPsNPfvKTqoBDRHiR1WJENl588UXcd999+Oyzz2q+AOD06dMe55SoMzG4ENkYHh7G559/XjfN/v378fTTT7cpR0TdhcGFyMZ3vvMdPPjggzXX33fffRgdHcU99/BPiMgO/zKIbPh8PrzwwgvYu3ev7frPP/8c4XC4zbki6h4MLkQ1jIyM4M6dO7brvva1r+Hxxx9vc46IugeDC1EN3/zmN/GNb3yjavnevXvxgx/8oP0ZIuoiDC5EdZw9e7aqauzOnTusEiNqgMGFqI5wOIy//vWv+nufz4dvfetbtnc0RHQXgwtRHV//+tdx5MgRvVPlnj17cPbsWY9zRdT5GFyIGhgbG8OePXsAAF988QWGh4c9zhFR52NwIWrg+eefx9/+9jcAwNNPP123/wsRbWJwIWpg//79erPj0dFRj3ND1B08H7jy/vvvbzjMBhEROfef//mfmJ6e9jILL3o+5P7nn3+OZ599FiMjI15nhXaBoaEhvPzyy3jqqaea+pwQAn/5y1/g9/u3KWed5Te/+Q1ef/11vPnmm15nhZo0Ojpqmi7CK54HFwAYHBzE4OCg19mgXeKJJ57g+daAHJmA5dR93n77ba+zAIDPXIiIaBswuBARkesYXIiIyHUMLkRE5DoGFyIich2DC1ELJicnMTk56XU2Ola5XEYikfA6G10pkUhA0zSvs7FlDC5EXUjTNH0wzU5TLpdx6dIlHD58GD6fDz6fr2YgluuNr04ky9vulclkTGlzuRxCoRB8Ph9CoVDVequ5uTnTcZ84cQJjY2Mol8vbcixtIzwGQCwsLHidDdoldsr5ls1mxXb++S4sLLS0/UqlIhRFEaurq/r7dDotAIhYLGb7mVKpJACIUqm0pTxvp9XVVQHA9mXMdzweFwBEPp8XQgiRz+cFABGPx223K9dby3p1dVUoiiIqlUrTeR0ZGREjIyNNf85lP+KdC1GX0TQNc3NzXmfD1vz8PILBIPr7+wEAfr9fH0V6enra9ld8IBAw/duJPv74YxSLRQgh9FepVEIsFjPlOxqNAgCCwaDp35WVlaptapqGt956y3Z//f39OHjwIObn590+lLZhcCFqUrlcRiaTQSgUsn2fy+X0KpGNjQ09jawuAe5WhYyPj2N9fV3ftl31kHVZPB5HLpczrQO8fw5ULpcRjUZx/Phx2/XxeBzhcLhhNZGkaRoymYx+jHNzc6aqIiflbkybSCT09cvLy00d28DAAPr6+kzLlpeX8dxzz1UdIwCsra0BgJ6Pqampqm3Oz8/jpZdeqrnPwcFBRKPR7q0e8/jWacdUU1B3cON8UxTFVJVhfC+rg4rFogAgVFXV92tNU6lUhKqqAoD48MMPhRB3q4iMf5pyW8Zl1vdCCBGLxWpWPTWrlWoxWVVXLBar1sltxWIxU7WRdb2RoigimUwKITbLRVEUU1WRk3I3fjadTgshhFhaWrLNQ7OM+zCSx7i6uirS6bRtdd/S0pKeZ7vv0ngs2Wy2qXx1SrUYgwvtKm6db04u9k7S2NXJt7otN7USXORF1Y5cLp/JGAOqcb0kA4Dxwiyfe8ggIT/XqKzkMx9rmq0E4nw+b8qHlfzREIvFqp6blEolPWjWOgYhNsvKem440SnBhdViRB6SdfKyrr6bORni3e/3688R6lX5LC4uAjA/h3n00UcBANeuXWsqXzK9tXpxK0PSv/XWWxgYGLBdl0gkcOzYMVQqFQCbM5kamxb/+te/xrlz5xruQ47A3a3nBoMLEbVVIBBAPp9HLpdDJBKx7dMxOztbtUxebOXzJqdkemF4GC9frZAB0a4BQiaTQTQaxalTp+D3+zE2NoZcLqdPXZDL5XDy5MmW9tttGFyIOoCqql5noa2CwSCy2SxyuZz+ENxIURQAsL2zabWsjA0ntsLuQb4UDocB3A2Evb29AIDz588DAEKhEB566KGaDTd2EgYXIg/JC97p06c9zsnWySDhtHe5oihIp9O21VNy8sCPPvpIXya32+wcM8lkEgCQSqX0bWxlBIGVlRW9OtNKBkVJBhm5vN7dU607qVgs1lI+vcbgQtQka3NY43t58TJeYK2/vmVTXE3TkEqloCiK6aIkf5nLwCObtQLA+Pg4APMve3mR9Lop8qFDhwBUBxd5/HZ3IcPDw7YXz1OnTkFRFMzMzOifu379OlRV1Z91OC33M2fOANh8xtLT0wOfz4fe3l49SMkmyoVCoeExFgoFHDt2rOb6CxcuALj7HcvvTi5vhmzGfPTo0aY/2wkYXIiaJKs65P+N73t6ekz/WtMDmw+mQ6EQenp60NfXh1QqZVr/s5/9DIqi4JFHHkEul0N/f7/+K//y5csA7vabeOONNzA2NubuAbboiSeeAAB88skn+jJ5IQc2y8Gu6mdqasr2F//8/DwURTF97tVXX9XTOC33QCCAYrGoBzFVVVEsFvV+K5VKBaqqOgrM9R7kA5v9YZaWlrCysgKfz4erV69iaWmp7mdqkeUoy7Xb+ESrT7XcyoDPh4WFBf02mGg7eXm+yQukx39yjly7dg2jo6NN51XeRV28eLGpz2maplcheSUUCiGbzXqaB6PJyUn09PQ0XZajo6MAgIWFhe3IllMv8s6FiFwTiUSwsrJiqspzwuvAsra2homJCU/zYFQoFFAoFBCJRLzOSssYXLaBdVgKIutzmp1KVmfNzMw4eobRCZaXl7Fv3z59PDSvra+vY3Z2FvPz854H3a1gcNkGly5dQjgcbro9/lbJsatCoVBL+641pLjP50MikUAul9sR80x4wfqcZicLBAJIpVK4ceOG11lxZGBgQG+M0AlyuRwuX77c0QN5OsHgsg2uXLnS9n1mMhnMzc0hlUohlUrhnXfeaXrkXPHlSK9SpVLRm0ueOHECc3NzO2OeCQ+40Xmvm/j9/qafFdCmixcvdn1gARhcdoSNjQ2Ew2FMTEzA7/fD7/dDVVWcP3++6aoJ40ltvCUPBoP6sB21elUTEUldGVxqDZ/dzBDcdsN5WzUa8tsuXSgUqtkTuF6+ZZWWpmkYHx9vqr/CrVu3AAAPPvigvuzAgQMAgHfffVdfttV+EIFAABcuXEAul8PNmzcdH5vT70R+XpaztdnqVodNJ6L26brgUi6XEYlEcPDgQQghcOHCBTzzzDN6ywr5rGNtbQ2KoqBYLCKXy+GVV14xbWdsbAzvv/++Xk3x3nvvVV14x8bG8Omnn+rVRbXGQhobG8PKygoqlQqy2Szee++9pvMtn5N88MEHUFUVf/rTnxyXiZyIyDjfhLwDcfu5z+OPPw4AeOedd/RlbnwniUQCg4ODEEJgaGgIb7zxhmm/9fZBRB2oHWMv14Mmh0BvNHw2mhiC2zqct6Io+nunQ37LOSyMw4fLobLt9tko361Ma2p3zPWWt7q9Wuvd+E6sZS3nNXG6D6eaPd92q1anOSbvdcqQ+/dua+TaBsbhs42mp6dtZ3urtw3j84X+/n5TB6pGQ37LqVvlL3hjaxO75oNO892NTQ/d+E5UVUVvby/S6TROnTqFQCBgevDtxj6k27dvY+/evU19Zre5ffs2gLt/B9Q9NjY2qmbN9ITX4Q1N/pJEk7+q7ZY12ka9NE631ew+neSpFjn5kt02a82WV0+9vMi7MuMdgxvfyYcffmiaWdA6QdJWysduO3zxtZNfnXDn0nXPXKStDJ8txzGqV1+/HUN+A+4N+21kl1f5sPzIkSOu7uu3v/0tANjOk76VYzt06BCy2Szy+TxUVUU0GrUdtdaN8ltYWLAdnZavuy85dIjX+eCr+VenDKXVdcHFjeGz5cV4dnZW38bGxoY+4izgfMhvmZ9GD5bdHvbbSE4+ZMyrHPTOzYmJyuUyXnvtNSiKYhqIz41j8/l80DQNwWAQV65cQT6fN83At53lR0TbQHgMaK5aTD7otb6KxaJpnXwwbny4Lh8Yl0olUxUMsFl9ZH0oryiKUBRF/1w6na6qZioWiwKAUBRFFItFIcTdxgByu83ku1XJZFKoqioqlYqoVCpCVVXTPN1CbM5x3ugBuLG8jI0L8vl8VXlIbnwnwGZVmyzDYrFoqhqrt49mNHu+7VZ8oN+9OuWBvudnTyt/7MViUcRiMf3iLS8w1gtPrWVCbF6s5DZisZgpsBjTJJNJ/bPpdNq2NVexWBSqqur5kcErnU6bLsRO8m1ssdYs2XJNURSxtLRUtb5RcLG7eMtXPB4Xq6urNT+71e9EBpp4PK7vz+k+msHg4gyDS/fqlODCIfdpV+H55kyrQ+6T9zjkPhER7VgMLkRE5DoGlw5Wbwh844uo07AlX+sSicSOGBiWwaWDCYft2qk7aJq2rT8Gtnv7TpXLZVy6dAmHDx/WfwDVGjC1234sFQoFU16N3RckJ/Mq1Utz4sSJHTG1BYMLUZtYR5Lutu07oWkaIpEIzp49i4GBAVQqFaTTaUxPT9sGGCHuziFUKpU6/seScZRxADh9+rTpvZN5lRqlCQaDmJiY6PqpLRhciNpA07SmJ2/rpO07NT8/j2AwqE8Z7Pf79XH4pqenkclkqj4jx+/rhgmy9u/fb6o1kB2yAWfzKjmde6m/vx8HDx7U51DqRgwuRA00mtfHrkrHuiwej+vVH3K5cR4fAJibm9OrWozD3LS6fWDrc/g0o1wuIxqN2g4NJPMYDodtA4ydRuXezFxBbswFtLGxgVAohMnJSaytrVWtdzKvktO5l4DNkUCi0WjXVo8xuBA10GheH+PU0FKxWDS9N47cLH/19vb26nXua2trOHfuHCqVCgDgkUce0QNMq9tvNzmS8sMPP2y7/uLFi4jFYgiHw47m4WlU7k7nCnJrLiCZfnp6Gk8++SRCoZDpwu9kXqVm5l6S5SjLteu0rb9mDWCPaWqjZs83p/P6wGb4HusyJ2mE2BxqB5ZRClrdfqta6aEvR0+wI5fLYZUA8xxI1s+5We5uzQUk85/P5/VjNQ6xVKv8jcudpDHuy3oeONEpPfR550JUR6N5fbZDMBgEANPAnd1genq6YRq/368/R6hX5eNmuVUUpg8AACAASURBVBvnAjJWGTrJr5Xf70cwGMTU1BSSyaTrM71a9wV033kgMbgQ1TE7O1u1TP7Rb+eFZScLBALI5/M1pw0H3C13mV643Ix/aGjIlBfjw30rOU2HkzQ7BYMLUR3bNa+PEzvtYmMUDAaRzWaRy+UQj8er1m9Hubs9l5Js6SU5mVepnXMveY3BhagOp/P6uEleBK19KDqdDBJO+2YoiqL3gbFys9y3ay4gTdNMeXEyr1Ircy/FYrEt5dMrDC5EdZw6dQqKomBmZkb/tXn9+nWoqmqaME3+gpWBwdhUVfbiNv5qtV7YZPNcTdOQSqWgKIqpCqXV7bezKfKhQ4cAVAcXWW52dyHDw8O2F08n5W7cntyncd9y/ZkzZwBsPmPp6emBz+dDb2+vHhhkE+V6rccymYyp+fLGxgZu3rxpOgf6+vqQTCZx9epVaJoGTdNw9epVJJNJvXWYkzTGfQDA0aNHa+aro3nankCwtRi1Vyvnm5N5fYrFot4KKpvNCiFE1Zw+shVYLBYzTZIGQJ+MDV+2QHJr+04miLPTSmsxOaGbcd4feXzGlx27eYwalbvddmvtq95cQLFYTKiqWncuJTlXkizffD7fMG2teZWcppGt46yT8zXSKa3FOJ8L7Sqddr7Jlkse/xlWaXU+F3nHdPHixaY+p2ma/sDeK6FQCNls1tM8GE1OTqKnp6fpsuR8LkS040QiEaysrNj2YK/H68CytraGiYkJT/NgVCgUUCgUEIlEvM5KyxhciDxiHcpkJ5D9WGZmZpruAe+V5eVl7Nu3Tx8PzWvr6+uYnZ3F/Py850F3KxhciDzS29tr+/9uFwgEkEqlcOPGDa+z4sjAwIDeGKET5HI5XL58uSsG8qznXq8zQLRbddpzFjf5/f6mnxXQpp1SbrxzISIi1zG4EBGR6xhciIjIdQwuRETkuo54oD86Ooq3337b62zQLvH666/zfGtADj0yNDTkcU6oWYuLix3RSdjzHvoTExP43e9+52UWiBr64x//iP/5n//BiRMnvM4KUUNjY2N1h/dvgxc9Dy5E3aDV4VCIdikO/0JERO5jcCEiItcxuBARkesYXIiIyHUMLkRE5DoGFyIich2DCxERuY7BhYiIXMfgQkRErmNwISIi1zG4EBGR6xhciIjIdQwuRETkOgYXIiJyHYMLERG5jsGFiIhcx+BCRESuY3AhIiLXMbgQEZHrGFyIiMh1DC5EROQ6BhciInIdgwsREbmOwYWIiFzH4EJERK5jcCEiItcxuBARkesYXIiIyHUMLkRE5DoGFyIich2DCxERuY7BhYiIXMfgQkRErrvX6wwQdaITJ04gn8/jwIEDAID/+7//g9/vxze/+U09zYcffoj/9//+H0ZGRrzKJlHHYnAhsrG8vAwhBP785z+blmuaZnr/8ccftzFXRN2D1WJENl599VXce2/9314+nw/Dw8NtyhFRd2FwIbLx/PPP44svvqi53ufz4fHHH8fXv/71NuaKqHswuBDZeOihh3D06FHcc4/9n8iePXvw/e9/v825IuoeDC5ENZw9exY+n8923d/+9jc8//zzbc4RUfdgcCGqYXBw0Hb5nj17cOzYMezfv7/NOSLqHgwuRDX84z/+I44fP449e/aYlgsh8MILL3iUK6LuwOBCVMcLL7wAIYRp2Z49e/Af//EfHuWIqDswuBDV8eyzz2Lv3r36+3vvvRenTp2C3+/3MFdEnY/BhaiOr371q/je976n93n54osvMDY25nGuiDofgwtRA6Ojo3qfl6985Sv43ve+53GOiDofgwtRA6dPn8YDDzwAAHjuuefwd3/3dx7niKjzeT622OrqKv7whz94nQ2iuh566CG8//77+Kd/+icsLi56nR2iuvr7+/HP//zPnubBJ6xNYdqdgRqd1IiIqDU//OEP8atf/crLLLzo+Z0LACwsLHDYcmoLn8/H882Ba9euYXR0tKoZNnW+0dFRfPbZZ15ng89ciIjIfQwuRETkOgYXIiJyHYMLERG5jsGFiIhcx+BCRESuY3AhasHk5CQmJye9zkbHKpfLSCQSXmejKyUSCWia5nU2tozBhagLaZrWsR2Qy+UyLl26hMOHD8Pn88Hn89UMxHK98dXJCoWCKa/j4+NVaXK5HEKhEEKhEHK5nO126qU5ceIExsbGUC6Xt+UY2qUjOlESdZupqSlP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\n",
      "text/plain": [
       "<IPython.core.display.Image object>"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from keras.utils import plot_model\n",
    "plot_model(model, to_file='model.png', show_shapes=True)\n",
    "from IPython.display import Image\n",
    "Image(filename='model.png') \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [],
   "source": [
    "model.compile(optimizer=SGD(0.01, 0.9), loss='kld')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Step 1: initialize cluster centers using k-means"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "c:\\users\\admin-karim\\appdata\\local\\programs\\python\\python35\\lib\\site-packages\\sklearn\\cluster\\k_means_.py:972: ConvergenceWarning: Number of distinct clusters (1) found smaller than n_clusters (5). Possibly due to duplicate points in X.\n",
      "  return_n_iter=True)\n"
     ]
    }
   ],
   "source": [
    "kmeans = KMeans(n_clusters=n_clusters, n_init=3)\n",
    "y_pred = kmeans.fit_predict(encoder.predict(x))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_pred_last = np.copy(y_pred)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [],
   "source": [
    "model.get_layer(name='clustering').set_weights([kmeans.cluster_centers_])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Step 2: deep clustering\n",
    "Compute p_i by first raising q_i to the second power and then normalizing by frequency per cluster:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [],
   "source": [
    "# computing an auxiliary target distribution\n",
    "def target_distribution(q):\n",
    "    weight = q ** 2 / q.sum(0)\n",
    "    return (weight.T / weight.sum(1)).T"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [],
   "source": [
    "loss = 0\n",
    "index = 0\n",
    "maxiter = 8000\n",
    "update_interval = 140\n",
    "index_array = np.arange(x.shape[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [],
   "source": [
    "tol = 0.001 # tolerance threshold to stop training"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Start training"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "c:\\users\\admin-karim\\appdata\\local\\programs\\python\\python35\\lib\\site-packages\\sklearn\\utils\\linear_assignment_.py:127: DeprecationWarning: The linear_assignment function is deprecated in 0.21 and will be removed from 0.23. Use scipy.optimize.linear_sum_assignment instead.\n",
      "  DeprecationWarning)\n",
      "c:\\users\\admin-karim\\appdata\\local\\programs\\python\\python35\\lib\\site-packages\\sklearn\\metrics\\cluster\\supervised.py:859: FutureWarning: The behavior of NMI will change in version 0.22. To match the behavior of 'v_measure_score', NMI will use average_method='arithmetic' by default.\n",
      "  FutureWarning)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Iter 0: acc = 0.37547, nmi = -1.12500, ari = 0.00000  ; loss= 0\n",
      "Iter 140: acc = 0.37547, nmi = -1.12500, ari = 0.00000  ; loss= 0.0\n",
      "delta_label  0.0 < tol  0.001\n",
      "Reached tolerance threshold. Stopping training.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "c:\\users\\admin-karim\\appdata\\local\\programs\\python\\python35\\lib\\site-packages\\sklearn\\utils\\linear_assignment_.py:127: DeprecationWarning: The linear_assignment function is deprecated in 0.21 and will be removed from 0.23. Use scipy.optimize.linear_sum_assignment instead.\n",
      "  DeprecationWarning)\n"
     ]
    }
   ],
   "source": [
    "for ite in range(int(maxiter)):\n",
    "    if ite % update_interval == 0:\n",
    "        q = model.predict(x, verbose=0)\n",
    "        p = target_distribution(q)  # update the auxiliary target distribution p\n",
    "\n",
    "        # evaluate the clustering performance\n",
    "        y_pred = q.argmax(1)\n",
    "        if y is not None:\n",
    "            acc = np.round(metrics.acc(y, y_pred), 5)\n",
    "            nmi = np.round(metrics.nmi(y, y_pred), 5)\n",
    "            ari = np.round(metrics.ari(y, y_pred), 5)\n",
    "            loss = np.round(loss, 5)\n",
    "            print('Iter %d: acc = %.5f, nmi = %.5f, ari = %.5f' % (ite, acc, nmi, ari), ' ; loss=', loss)\n",
    "\n",
    "        # check stop criterion - model convergence\n",
    "        delta_label = np.sum(y_pred != y_pred_last).astype(np.float32) / y_pred.shape[0]\n",
    "        y_pred_last = np.copy(y_pred)\n",
    "        if ite > 0 and delta_label < tol:\n",
    "            print('delta_label ', delta_label, '< tol ', tol)\n",
    "            print('Reached tolerance threshold. Stopping training.')\n",
    "            break\n",
    "    idx = index_array[index * batch_size: min((index+1) * batch_size, x.shape[0])]\n",
    "    loss = model.train_on_batch(x=x[idx], y=p[idx])\n",
    "    index = index + 1 if (index + 1) * batch_size <= x.shape[0] else 0\n",
    "\n",
    "model.save_weights(save_dir + '/DEC_model_final.h5')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Load the clustering model trained weights"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [],
   "source": [
    "model.load_weights(save_dir + '/DEC_model_final.h5')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Final Evaluation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 81,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Acc = 0.37807, nmi = 0.31678, ari = 0.22979  ; loss= 0.1373\n"
     ]
    }
   ],
   "source": [
    "# Eval.\n",
    "q = model.predict(x, verbose=0)\n",
    "p = target_distribution(q)  # update the auxiliary target distribution p\n",
    "\n",
    "# evaluate the clustering performance\n",
    "y_pred = q.argmax(1)\n",
    "if y is not None:\n",
    "    acc = np.round(metrics.acc(y, y_pred), 5)\n",
    "    nmi = np.round(metrics.nmi(y, y_pred), 5)\n",
    "    ari = np.round(metrics.ari(y, y_pred), 5)\n",
    "    loss = np.round(loss, 5)\n",
    "    print('Acc = %.5f, nmi = %.5f, ari = %.5f' % (acc, nmi, ari), ' ; loss=', loss)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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mTNndObMGf3www9atWqVXn/9dfn6+pb5N9CaCwAAAACVxLvvvqsFCxaUaezp06c1evRoJScnq1q1aho1apQWL16smJgYRUVFycvLS4mJiRo7dqySkpLs3mP58uWaOXOmDMNQRESEXnrpJS1btkyvv/662rZtK0n65ptvNHnyZId+BxVRAAAAAB7L6uoAyklOTo5efPFFffTRR2We89prryklJUVSflWzZ8+etmudO3dWx44d9c9//lOnT5/WW2+9dVEymZaWpldeeUWS1KhRIy1btkzBwcGSpLZt2+qWW27R+PHjtX79eq1cuVJDhw7VNddcU6bYqIgCAAAAgBv79ddfdc8999iSUG9v71LnnDlzRqtWrZIk3XjjjUWS0AK33367br75ZknSihUrdPbs2SLXP/74Y507d06S9Pjjj9uS0AI+Pj6aOnWqAgICJElz584t828iEQUAAAAANzV9+nQNHjxYe/fulST17t1bw4cPL3Xed999p7y8PEnSXXfdVey4u+++W5KUm5urb7/9tsi1tWvXSpJq1Kih3r17251fq1Yt9ejRQ5L0/fffKzMzs9TYJBJRAAAAAB7McNNPWe3evVuGYSgkJETR0dGaPXu2qlevXuq8nTt32o4jIyOLHdehQwdZLPlbC2/dutV2Pjc315b8dujQocQqbKdOnSRJmZmZ2rVrV6mxSSSiAAAAAOC2goKCNGrUKK1du1aDBg0q87zDhw/b5oeGhhY77rLLLrNdL5gjSceOHVNubq4kKSIiosTvatCgge04Li6uTPGxWREAAAAAuKmZM2fKy8vx+uGpU6ckSeHh4aWOvfzyy5WcnGybU3i+JF1xxRUlzi/8HYXnlYREFAAAAIDHsjrUCOt+nElCJdk2HgoMDCx1bEGrb3p6uu1cWlqa7bi0exRsViTJtrlRaWjNBQAAAAAPk5OTI0ny8/MrdWzBmII5fz329fUtcb6/v7/deSUhEQUAAAAAD1OwuVDBRkRlUXhs4c2JnL1HSWjNBQAAAOCxrK4OwEWqV6+us2fPKjs7u9SxBWMKV08L78xb2j2ysrJsx2WpwEpURAEAAADA4xQ811mW93pmZGRIkoKDgy+aX5Z7FL5e+B4lIREFAAAAAA9TsNNtQkJCqWMTExMlSXXq1LGdq1evnu24tHsUvl74HiUhEQUAAADgsQw3/VS0pk2bSpJS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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x22e066bbbe0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import seaborn as sns\n",
    "import matplotlib \n",
    "%matplotlib inline\n",
    "\n",
    "import sklearn.metrics\n",
    "import matplotlib.pyplot as plt\n",
    "sns.set(font_scale=3)\n",
    "confusion_matrix = sklearn.metrics.confusion_matrix(y, y_pred)\n",
    "\n",
    "plt.figure(figsize=(16, 14))\n",
    "sns.heatmap(confusion_matrix, annot=True, fmt=\"d\", annot_kws={\"size\": 20});\n",
    "plt.title(\"Confusion matrix\", fontsize=30)\n",
    "plt.ylabel('True label', fontsize=25)\n",
    "plt.xlabel('Clustering label', fontsize=25)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Break down Accuracy metric\n",
    "\n",
    "linear assignment- [Munkres' Assignment Algorithm](http://csclab.murraystate.edu/~bob.pilgrim/445/munkres.html)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "c:\\users\\admin-karim\\appdata\\local\\programs\\python\\python35\\lib\\site-packages\\sklearn\\utils\\linear_assignment_.py:127: DeprecationWarning: The linear_assignment function is deprecated in 0.21 and will be removed from 0.23. Use scipy.optimize.linear_sum_assignment instead.\n",
      "  DeprecationWarning)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "0.37546933667083854"
      ]
     },
     "execution_count": 65,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.utils.linear_assignment_ import linear_assignment\n",
    "\n",
    "y_true = y.astype(np.int64)\n",
    "D = max(y_pred.max(), y_true.max()) + 1\n",
    "w = np.zeros((D, D), dtype=np.int64)\n",
    "# Confusion matrix.\n",
    "for i in range(y_pred.size):\n",
    "    w[y_pred[i], y_true[i]] += 1\n",
    "ind = linear_assignment(-w)\n",
    "\n",
    "sum([w[i, j] for i, j in ind]) * 1.0 / y_pred.size"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[300,  78, 146, 141, 134],\n",
       "       [  0,   0,   0,   0,   0],\n",
       "       [  0,   0,   0,   0,   0],\n",
       "       [  0,   0,   0,   0,   0],\n",
       "       [  0,   0,   0,   0,   0]], dtype=int64)"
      ]
     },
     "execution_count": 66,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "w"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0, 0],\n",
       "       [1, 1],\n",
       "       [2, 2],\n",
       "       [3, 3],\n",
       "       [4, 4]])"
      ]
     },
     "execution_count": 67,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ind"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 0, 0, 0, 0], dtype=int64)"
      ]
     },
     "execution_count": 68,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "w.argmax(1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [],
   "source": [
    "def vis_data(x_train_encoded, y_train, vis_dim, n_predict, n_train, build_anim):\n",
    "    cmap = plt.get_cmap('rainbow', 10)\n",
    "\n",
    "    # 3-dim vis: show one view, then compile animated .gif of many angled views\n",
    "    if vis_dim == 3:\n",
    "        # Simple static figure\n",
    "        fig = plt.figure()\n",
    "        ax = plt.axes(projection='3d')\n",
    "        p = ax.scatter3D(x_train_encoded[:,0], x_train_encoded[:,1], x_train_encoded[:,2], \n",
    "                c=y_train[:n_predict], cmap=cmap, edgecolor='black')\n",
    "        fig.colorbar(p, drawedges=True)\n",
    "        plt.show()\n",
    "\n",
    "        # Build animation from many static figures\n",
    "        if build_anim:\n",
    "            angles = np.linspace(180, 360, 20)\n",
    "            i = 0\n",
    "            for angle in angles:\n",
    "                fig = plt.figure()\n",
    "                ax = plt.axes(projection='3d')\n",
    "                ax.view_init(10, angle)\n",
    "                p = ax.scatter3D(x_train_encoded[:,0], x_train_encoded[:,1], x_train_encoded[:,2], \n",
    "                        c=y_train[:n_predict], cmap=cmap, edgecolor='black')\n",
    "                fig.colorbar(p, drawedges=True)\n",
    "                outfile = 'anim/3dplot_step_' + chr(i + 97) + '.png'\n",
    "                plt.savefig(outfile, dpi=96)\n",
    "                i += 1\n",
    "            call(['convert', '-delay', '50', 'anim/3dplot*', 'anim/3dplot_anim_' + str(n_train) + '.gif'])\n",
    "\n",
    "    # 2-dim vis: plot and colorbar.\n",
    "    elif vis_dim == 2:\n",
    "        plt.scatter(x_train_encoded[:,0], x_train_encoded[:,1], \n",
    "                c=y_train[:n_predict], edgecolor='black', cmap=cmap)\n",
    "        plt.colorbar(drawedges=True)\n",
    "        plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Encode a number of MNIST digits, then perform t-SNE dim-reduction.\n",
    "x_train_predict = encoder.predict(x)\n",
    "from sklearn import manifold\n",
    "%matplotlib inline\n",
    "\n",
    "#print \"Performing t-SNE dimensionality reduction...\"\n",
    "x_train_encoded = manifold.TSNE(n_components=2).fit_transform(x_train_predict)\n",
    "#np.save('%sx_%sdim_tnse_%s.npy' % (266, 2, 266), x_train_encoded)\n",
    "#x_train_encoded = np.load(s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [
    {
     "ename": "ValueError",
     "evalue": "Invalid RGBA argument: 3.0",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mKeyError\u001b[0m                                  Traceback (most recent call last)",
      "\u001b[1;32mc:\\users\\admin-karim\\appdata\\local\\programs\\python\\python35\\lib\\site-packages\\matplotlib\\colors.py\u001b[0m in \u001b[0;36mto_rgba\u001b[1;34m(c, alpha)\u001b[0m\n\u001b[0;32m    140\u001b[0m     \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 141\u001b[1;33m         \u001b[0mrgba\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0m_colors_full_map\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcache\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mc\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0malpha\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m    142\u001b[0m     \u001b[1;32mexcept\u001b[0m \u001b[1;33m(\u001b[0m\u001b[0mKeyError\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mTypeError\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m  \u001b[1;31m# Not in cache, or unhashable.\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mKeyError\u001b[0m: (3.0, None)",
      "\nDuring handling of the above exception, another exception occurred:\n",
      "\u001b[1;31mValueError\u001b[0m                                Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-73-2e8a4de58014>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m      7\u001b[0m \u001b[0mbuild_anim\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;32mFalse\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      8\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 9\u001b[1;33m \u001b[0mvis_data\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mx_train_encoded\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0my\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mvis_dim\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mn_predict\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mn_train\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mbuild_anim\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;32m<ipython-input-69-acb0cbc04314>\u001b[0m in \u001b[0;36mvis_data\u001b[1;34m(x_train_encoded, y_train, vis_dim, n_predict, n_train, build_anim)\u001b[0m\n\u001b[0;32m     31\u001b[0m     \u001b[1;32melif\u001b[0m \u001b[0mvis_dim\u001b[0m \u001b[1;33m==\u001b[0m \u001b[1;36m2\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     32\u001b[0m         plt.scatter(x_train_encoded[:,0], x_train_encoded[:,1], \n\u001b[1;32m---> 33\u001b[1;33m                 c=y_train[:n_predict], edgecolor='black', cmap=cmap)\n\u001b[0m\u001b[0;32m     34\u001b[0m         \u001b[0mplt\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcolorbar\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdrawedges\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mTrue\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     35\u001b[0m         \u001b[0mplt\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mshow\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32mc:\\users\\admin-karim\\appdata\\local\\programs\\python\\python35\\lib\\site-packages\\matplotlib\\pyplot.py\u001b[0m in \u001b[0;36mscatter\u001b[1;34m(x, y, s, c, marker, cmap, norm, vmin, vmax, alpha, linewidths, verts, edgecolors, hold, data, **kwargs)\u001b[0m\n\u001b[0;32m   3432\u001b[0m                          \u001b[0mvmin\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mvmin\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mvmax\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mvmax\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0malpha\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0malpha\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m   3433\u001b[0m                          \u001b[0mlinewidths\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mlinewidths\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mverts\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mverts\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 3434\u001b[1;33m                          edgecolors=edgecolors, data=data, **kwargs)\n\u001b[0m\u001b[0;32m   3435\u001b[0m     \u001b[1;32mfinally\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m   3436\u001b[0m         \u001b[0max\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_hold\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mwashold\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32mc:\\users\\admin-karim\\appdata\\local\\programs\\python\\python35\\lib\\site-packages\\matplotlib\\__init__.py\u001b[0m in \u001b[0;36minner\u001b[1;34m(ax, *args, **kwargs)\u001b[0m\n\u001b[0;32m   1896\u001b[0m                     warnings.warn(msg % (label_namer, func.__name__),\n\u001b[0;32m   1897\u001b[0m                                   RuntimeWarning, stacklevel=2)\n\u001b[1;32m-> 1898\u001b[1;33m             \u001b[1;32mreturn\u001b[0m \u001b[0mfunc\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0max\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m*\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m   1899\u001b[0m         \u001b[0mpre_doc\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0minner\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m__doc__\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m   1900\u001b[0m         \u001b[1;32mif\u001b[0m \u001b[0mpre_doc\u001b[0m \u001b[1;32mis\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32mc:\\users\\admin-karim\\appdata\\local\\programs\\python\\python35\\lib\\site-packages\\matplotlib\\axes\\_axes.py\u001b[0m in \u001b[0;36mscatter\u001b[1;34m(self, x, y, s, c, marker, cmap, norm, vmin, vmax, alpha, linewidths, verts, edgecolors, **kwargs)\u001b[0m\n\u001b[0;32m   4032\u001b[0m                 \u001b[0moffsets\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0moffsets\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m   4033\u001b[0m                 \u001b[0mtransOffset\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mpop\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'transform'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mtransData\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 4034\u001b[1;33m                 \u001b[0malpha\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0malpha\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m   4035\u001b[0m                 )\n\u001b[0;32m   4036\u001b[0m         \u001b[0mcollection\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mset_transform\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmtransforms\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mIdentityTransform\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32mc:\\users\\admin-karim\\appdata\\local\\programs\\python\\python35\\lib\\site-packages\\matplotlib\\collections.py\u001b[0m in \u001b[0;36m__init__\u001b[1;34m(self, paths, sizes, **kwargs)\u001b[0m\n\u001b[0;32m    900\u001b[0m         \"\"\"\n\u001b[0;32m    901\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 902\u001b[1;33m         \u001b[0mCollection\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m__init__\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m    903\u001b[0m         \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mset_paths\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mpaths\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    904\u001b[0m         \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mset_sizes\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0msizes\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32mc:\\users\\admin-karim\\appdata\\local\\programs\\python\\python35\\lib\\site-packages\\matplotlib\\collections.py\u001b[0m in \u001b[0;36m__init__\u001b[1;34m(self, edgecolors, facecolors, linewidths, linestyles, antialiaseds, offsets, transOffset, norm, cmap, pickradius, hatch, urls, offset_position, zorder, **kwargs)\u001b[0m\n\u001b[0;32m    138\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    139\u001b[0m         \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_hatch_color\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mmcolors\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mto_rgba\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmpl\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrcParams\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m'hatch.color'\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 140\u001b[1;33m         \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mset_facecolor\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mfacecolors\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m    141\u001b[0m         \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mset_edgecolor\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0medgecolors\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    142\u001b[0m         \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mset_linewidth\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mlinewidths\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32mc:\\users\\admin-karim\\appdata\\local\\programs\\python\\python35\\lib\\site-packages\\matplotlib\\collections.py\u001b[0m in \u001b[0;36mset_facecolor\u001b[1;34m(self, c)\u001b[0m\n\u001b[0;32m    679\u001b[0m         \"\"\"\n\u001b[0;32m    680\u001b[0m         \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_original_facecolor\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mc\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 681\u001b[1;33m         \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_set_facecolor\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mc\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m    682\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    683\u001b[0m     \u001b[1;32mdef\u001b[0m \u001b[0mset_facecolors\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mc\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32mc:\\users\\admin-karim\\appdata\\local\\programs\\python\\python35\\lib\\site-packages\\matplotlib\\collections.py\u001b[0m in \u001b[0;36m_set_facecolor\u001b[1;34m(self, c)\u001b[0m\n\u001b[0;32m    664\u001b[0m         \u001b[1;32mexcept\u001b[0m \u001b[0mAttributeError\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    665\u001b[0m             \u001b[1;32mpass\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 666\u001b[1;33m         \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_facecolors\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mmcolors\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mto_rgba_array\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mc\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_alpha\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m    667\u001b[0m         \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstale\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;32mTrue\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    668\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32mc:\\users\\admin-karim\\appdata\\local\\programs\\python\\python35\\lib\\site-packages\\matplotlib\\colors.py\u001b[0m in \u001b[0;36mto_rgba_array\u001b[1;34m(c, alpha)\u001b[0m\n\u001b[0;32m    237\u001b[0m     \u001b[0mresult\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mempty\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mc\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m4\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mfloat\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    238\u001b[0m     \u001b[1;32mfor\u001b[0m \u001b[0mi\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mcc\u001b[0m \u001b[1;32min\u001b[0m \u001b[0menumerate\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mc\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 239\u001b[1;33m         \u001b[0mresult\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mi\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mto_rgba\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mcc\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0malpha\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m    240\u001b[0m     \u001b[1;32mreturn\u001b[0m \u001b[0mresult\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    241\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32mc:\\users\\admin-karim\\appdata\\local\\programs\\python\\python35\\lib\\site-packages\\matplotlib\\colors.py\u001b[0m in \u001b[0;36mto_rgba\u001b[1;34m(c, alpha)\u001b[0m\n\u001b[0;32m    141\u001b[0m         \u001b[0mrgba\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0m_colors_full_map\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcache\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mc\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0malpha\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    142\u001b[0m     \u001b[1;32mexcept\u001b[0m \u001b[1;33m(\u001b[0m\u001b[0mKeyError\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mTypeError\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m  \u001b[1;31m# Not in cache, or unhashable.\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 143\u001b[1;33m         \u001b[0mrgba\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0m_to_rgba_no_colorcycle\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mc\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0malpha\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m    144\u001b[0m         \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    145\u001b[0m             \u001b[0m_colors_full_map\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcache\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mc\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0malpha\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mrgba\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32mc:\\users\\admin-karim\\appdata\\local\\programs\\python\\python35\\lib\\site-packages\\matplotlib\\colors.py\u001b[0m in \u001b[0;36m_to_rgba_no_colorcycle\u001b[1;34m(c, alpha)\u001b[0m\n\u001b[0;32m    192\u001b[0m         \u001b[1;31m# float)` and `np.array(...).astype(float)` all convert \"0.5\" to 0.5.\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    193\u001b[0m         \u001b[1;31m# Test dimensionality to reject single floats.\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 194\u001b[1;33m         \u001b[1;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Invalid RGBA argument: {!r}\"\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0morig_c\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m    195\u001b[0m     \u001b[1;31m# Return a tuple to prevent the cached value from being modified.\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    196\u001b[0m     \u001b[0mc\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mtuple\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mc\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mastype\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mfloat\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mValueError\u001b[0m: Invalid RGBA argument: 3.0"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x22e06b79940>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Visualize result.\n",
    "train_new = False\n",
    "n_train = 699\n",
    "predict_new = False\n",
    "n_predict = 699\n",
    "vis_dim = 2\n",
    "build_anim = False\n",
    "    \n",
    "vis_data(x_train_encoded, y, vis_dim, n_predict, n_train, build_anim)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
